В вашем распоряжении данные о поведении клиентов, которые уже перешли на эти тарифы (из проекта курса «Статистический анализ данных»). Нужно построить модель для задачи классификации, которая выберет подходящий тариф. Предобработка данных не понадобится — вы её уже сделали.
Постройте модель с максимально большим значением accuracy. Чтобы сдать проект успешно, нужно довести долю правильных ответов по крайней мере до 0.75. Проверьте accuracy на тестовой выборке самостоятельно.
!pip install plotly.express
Requirement already satisfied: plotly.express in c:\programdata\anaconda3\lib\site-packages (0.4.1) Requirement already satisfied: pandas>=0.20.0 in c:\programdata\anaconda3\lib\site-packages (from plotly.express) (1.1.3) Requirement already satisfied: statsmodels>=0.9.0 in c:\programdata\anaconda3\lib\site-packages (from plotly.express) (0.12.0) Requirement already satisfied: patsy>=0.5 in c:\programdata\anaconda3\lib\site-packages (from plotly.express) (0.5.1) Requirement already satisfied: plotly>=4.1.0 in c:\programdata\anaconda3\lib\site-packages (from plotly.express) (5.3.1) Requirement already satisfied: numpy>=1.11 in c:\programdata\anaconda3\lib\site-packages (from plotly.express) (1.19.2) Requirement already satisfied: scipy>=0.18 in c:\programdata\anaconda3\lib\site-packages (from plotly.express) (1.5.2) Requirement already satisfied: python-dateutil>=2.7.3 in c:\programdata\anaconda3\lib\site-packages (from pandas>=0.20.0->plotly.express) (2.8.1) Requirement already satisfied: pytz>=2017.2 in c:\programdata\anaconda3\lib\site-packages (from pandas>=0.20.0->plotly.express) (2020.1) Requirement already satisfied: six in c:\programdata\anaconda3\lib\site-packages (from patsy>=0.5->plotly.express) (1.15.0) Requirement already satisfied: tenacity>=6.2.0 in c:\programdata\anaconda3\lib\site-packages (from plotly>=4.1.0->plotly.express) (8.0.1)
import pandas as pd
import plotly.express as px
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.dummy import DummyClassifier
from sklearn.metrics import accuracy_score
df = pd.read_csv('users_behavior.csv')
df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 3214 entries, 0 to 3213 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 calls 3214 non-null float64 1 minutes 3214 non-null float64 2 messages 3214 non-null float64 3 mb_used 3214 non-null float64 4 is_ultra 3214 non-null int64 dtypes: float64(4), int64(1) memory usage: 125.7 KB
df.head()
| calls | minutes | messages | mb_used | is_ultra | |
|---|---|---|---|---|---|
| 0 | 40.0 | 311.90 | 83.0 | 19915.42 | 0 |
| 1 | 85.0 | 516.75 | 56.0 | 22696.96 | 0 |
| 2 | 77.0 | 467.66 | 86.0 | 21060.45 | 0 |
| 3 | 106.0 | 745.53 | 81.0 | 8437.39 | 1 |
| 4 | 66.0 | 418.74 | 1.0 | 14502.75 | 0 |
df.describe()
| calls | minutes | messages | mb_used | is_ultra | |
|---|---|---|---|---|---|
| count | 3214.000000 | 3214.000000 | 3214.000000 | 3214.000000 | 3214.000000 |
| mean | 63.038892 | 438.208787 | 38.281269 | 17207.673836 | 0.306472 |
| std | 33.236368 | 234.569872 | 36.148326 | 7570.968246 | 0.461100 |
| min | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 25% | 40.000000 | 274.575000 | 9.000000 | 12491.902500 | 0.000000 |
| 50% | 62.000000 | 430.600000 | 30.000000 | 16943.235000 | 0.000000 |
| 75% | 82.000000 | 571.927500 | 57.000000 | 21424.700000 | 1.000000 |
| max | 244.000000 | 1632.060000 | 224.000000 | 49745.730000 | 1.000000 |
df.corr()
| calls | minutes | messages | mb_used | is_ultra | |
|---|---|---|---|---|---|
| calls | 1.000000 | 0.982083 | 0.177385 | 0.286442 | 0.207122 |
| minutes | 0.982083 | 1.000000 | 0.173110 | 0.280967 | 0.206955 |
| messages | 0.177385 | 0.173110 | 1.000000 | 0.195721 | 0.203830 |
| mb_used | 0.286442 | 0.280967 | 0.195721 | 1.000000 | 0.198568 |
| is_ultra | 0.207122 | 0.206955 | 0.203830 | 0.198568 | 1.000000 |
fig = px.scatter_matrix(df,title = 'Матрица зависмости парметров', template = 'plotly_dark')
fig.show()
Загрузили датасет, просмотрели набор данных, данные уже подготовлены, нету пропусков, и ошибок в типах данных.Провели анализ корреляции парметров. Можем приступать к работе с моделями. Так как парметр звонки и минуты сильно звязаны в модели будем использовать только минуты.
Для начала определим, что у насбудет признаками, а что целью. В нашем случае цель-это тариф, а остальные столбцы - признаки.
features = df.drop(['is_ultra','calls'], axis=1)
target = df['is_ultra']
features_train, features_valid, target_train, target_valid = train_test_split(
features, target, test_size=0.4, random_state=12345)
features_test, features_valid, target_test, target_valid = train_test_split(
features_valid, target_valid, test_size=0.5, random_state=12345)
print('Валидационная выборка',len(features_valid))
print('Тестовая выборка',len(features_test))
print('обучающая выборка',len(features_train))
Валидационная выборка 643 Тестовая выборка 643 обучающая выборка 1928
Разделили выборки на валидационную, тестовую и обучающую, примерно в отношении 1:1:3.
best_model = None
best_result = 0
for depth in range(1, 6):
model = DecisionTreeClassifier(random_state=12345, max_depth=depth)
model.fit(features_train,target_train)
result = model.score(features_valid,target_valid)
if result > best_result:
best_model = model
best_result = result
depth_best = depth
print("Accuracy лучшей модели:", best_result,'depth:',depth_best)
Accuracy лучшей модели: 0.7884914463452566 depth: 5
best_model = None
best_result = 0
for est in range(1, 11):
for depth in range(1,6):
model = RandomForestClassifier(random_state=12345, n_estimators= est,max_depth = depth)
model.fit(features_train,target_train)
result = model.score(features_valid,target_valid)
if result > best_result:
best_model = model
best_result = result
best = est
max_depth = depth
print("Accuracy наилучшей модели на валидационной выборке:", best_result,'Количество деревьев:',best, 'depth',max_depth)
Accuracy наилучшей модели на валидационной выборке: 0.7822706065318819 Количество деревьев: 7 depth 5
model = LogisticRegression(random_state=12345)
model.fit(features_train, target_train)
result = model.score(features_valid,target_valid)
print("Accuracy модели логистической регрессии на валидационной выборке:", result)
Accuracy модели логистической регрессии на валидационной выборке: 0.6982892690513219
Рассмотрели три модели:
Лучший результать accuracy показала модель случайного леса с такими гиперпараметрами, как количество деревьев - 4, глубина деревьев - 5.
model = RandomForestClassifier(random_state=12345, n_estimators= 4,max_depth = 5)
model.fit(features_train,target_train )
result = model.score(features_test,target_test)
result
0.7807153965785381
Проверили на тестовой выборке лучшую модель, показатель чуть ниже, чем на валидационной, но результат по-прежнему хороший, больше заданного.
result = model.score(df.drop(['is_ultra','calls'], axis=1),df['is_ultra'])
result
0.7999377722464219
Для проверки на адекватность, загрузили в модель наш датасет целиком, результат выше, чем на тестовой выборке.
strategies = ['most_frequent']
dummy_results = []
for strategy in strategies:
dc = DummyClassifier(strategy = strategy, random_state = 12345)
dc.fit(features_train, target_train)
result = dc.score(features_test, target_test)
dummy_results.append({strategy: result})
pd.DataFrame(dummy_results)
| most_frequent | |
|---|---|
| 0 | 0.706065 |